package com.bang.concurrency.example.deadLock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @ClassName: DeadLock
 * @Desc: 模拟死锁
 * @auther: BANG
 * @Date: 2019/10/09 16:20
 * @Version: 1.0
 * @Modified By:
 *
 * 一个简单的死锁类
 * 当DeadLock类的对象flag==1时（td1），先锁定o1,睡眠500毫秒
 * 而td1在睡眠的时候另一个flag==0的对象（td2）线程启动，先锁定o2,睡眠500毫秒
 * td1睡眠结束后需要锁定o2才能继续执行，而此时o2已被td2锁定；
 * td2睡眠结束后需要锁定o1才能继续执行，而此时o1已被td1锁定；
 * td1、td2相互等待，都需要得到对方锁定的资源才能继续执行，从而死锁。
 *
 */
@Slf4j
public class DeadLock implements Runnable {


    private Integer flag;

    private static Object lock1 = new Object();

    private static Object lock2 = new Object();


    public DeadLock(Integer flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        log.info("flag = {}", flag);
        if (flag == 1) {
            synchronized (lock1) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    log.info("1");
                }
            }

        } else {
            synchronized (lock2) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    log.info("0");
                }
            }

        }
    }

    public static void main(String[] args) {
        DeadLock deadLock1 = new DeadLock(1);
        DeadLock deadLock2 = new DeadLock(0);
        ExecutorService service = Executors.newCachedThreadPool();
        service.execute(deadLock1);
        service.execute(deadLock2);
        log.info("执行完毕------------->");
        service.shutdown();
    }


}
